/*
 * ourZoom.java
 *
 * Created on 27 maggio 2008, 11.05
 */

package our.gui;

import java.awt.Cursor;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Vector;
import java.util.logging.Level;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.KeyStroke;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

/**
 *
 * @author  keysman
 */
public abstract class ourZoom extends javax.swing.JDialog implements ourInterfaceZoom {
    private String[] strRet = null; // Valore di ritorno
    private JButton[] butLettere = null;
    private int W = 450; // Larghezza della finestra
    private int H = 450; // Altezza della finestra
    //private ourZoom CHILD = null; // Riferimento alla sottoclasse
    protected boolean ISZOOMONZOOMENABLED = false;
    protected boolean bAsc = false;
    private boolean _ISTABLESET = false; // Flag che indica se la griglia è stata configurata
    private String[] _STRCAPTION = null; // Array contenente gli header delle colonne della griglia
    private boolean _RECORDSFOUND = true; // Flag che indica se una ricerca ha prodotto risultati o meno
    
    private String _DEFAULTFILTER = "-"; // Il filtro di default

    private String _DB_TABLE = ""; // Tabella alla quale è assiciato lo zoom

    private String _SORT_FIELD = ""; // Nome del campo del DB su cui è mantuenuta ordinata la griglia

    private String[] _STRFIELDSONDB = null; // I campi del db corrispondenti alle intestazioni della griglia

    private String _TROVA_FIELD = ""; // Il campo in cui cercare quando premo il pulsante 'Trova'

    private String _ZoomOnZoomClassName = null; // Nome della classe da visualizzare per lo ZoomOnZoom

    public String getZoomOnZoomClassName() {
        return _ZoomOnZoomClassName;
    }

    public void setZoomOnZoomClassName(String _ZoomOnZoomClassName) {
        this._ZoomOnZoomClassName = _ZoomOnZoomClassName;
    }

    public String getDB_TABLE() {
        return _DB_TABLE;
    }

    public void setDB_TABLE(String _DB_TABLE, String _SORT_FIELD, String _TROVA_FIELD) {
        this._DB_TABLE = _DB_TABLE;
        this._SORT_FIELD = _SORT_FIELD;
        this._TROVA_FIELD = _TROVA_FIELD;

    }

    public Object[] CallZoom(Object[] KEY) {
        our.gui.ourForm form;
        Class formDefinition;
        Class[] ArgsClass = new Class[] { java.awt.Frame.class, boolean.class };
        Object[] ArgsVals = new Object[] {new java.awt.Frame(), new Boolean(true) };
        java.lang.reflect.Constructor ArgsConstructor;
        try {
            formDefinition = Class.forName(getZoomOnZoomClassName());
            ArgsConstructor = formDefinition.getConstructor(ArgsClass);
            form = (our.gui.ourForm)ArgsConstructor.newInstance(ArgsVals);
            form.isZoomOnZoom(true);
            form.setUsersPKValues(KEY);
            //form.GOTO(KEY);
            form.setVisible(true);
            return form.getKeyFieldVals();
        }  catch (ClassNotFoundException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        } catch (NoSuchMethodException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        } catch (InstantiationException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        } catch (IllegalAccessException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        } catch (IllegalArgumentException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        } catch (InvocationTargetException e) {
            our.gui.utils.logger.log(Level.SEVERE, e.toString());
            javax.swing.JOptionPane.showMessageDialog(null, e.toString(), "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }

        return null;
    }

 /*   public Object[] CALLZOOM(Object[] KEY, String strFormAnagrafica) {
        our.gui.ourForm form;
        Class formDefinition;
        Class[] ArgsClass = new Class[] { java.awt.Frame.class };
        Object[] ArgsVals = new Object[] { new java.awt.Frame() };
        java.lang.reflect.Constructor ArgsConstructor;

        try {
            Class f = (Class) Class.forName(strFormAnagrafica).newInstance();


            formDefinition = Class.forName(strFormAnagrafica);
            ArgsConstructor = formDefinition.getConstructor(ArgsClass);
            form = (our.gui.ourForm)commonObjectClass.createObject(ArgsConstructor, ArgsVals);
            /*Object obj[] = new Object[] { str };
            _STRRET = (String[]) zoom.CALLZOOM(obj);
            if( (_STRRET.length==1) && (_STRRET[0].length()==0) )
            {
                _STRRET = null;
            } else {
                zoom.findUsingKey(_STRRET[0]);
                _STRRET = zoom.getSelectedEntry();
            }*/
  /*      } catch (java.lang.IllegalAccessException e) {
        } catch (java.lang.InstantiationException e) {
        } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
            System.out.println(e);
        }
        return null;
        //slkdfjhgkl
    }*/

    /*public Object[] CALLZOOM(Object[] KEY) {
        our.gui.ourForm form;
        Class formDefinition;
        Class[] ArgsClass = new Class[] { java.awt.Frame.class };
        Object[] ArgsVals = new Object[] { new java.awt.Frame() };
        java.lang.reflect.Constructor ArgsConstructor;

        try {
            formDefinition = Class.forName("cippa de mink");
            ArgsConstructor = formDefinition.getConstructor(ArgsClass);
            form = (our.gui.ourForm)commonObjectClass.createObject(ArgsConstructor, ArgsVals);
            /*Object obj[] = new Object[] { str };
            _STRRET = (String[]) zoom.CALLZOOM(obj);
            if( (_STRRET.length==1) && (_STRRET[0].length()==0) )
            {
                _STRRET = null;
            } else {
                zoom.findUsingKey(_STRRET[0]);
                _STRRET = zoom.getSelectedEntry();
            }*/
   /*     } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
            System.out.println(e);
        }
        return null;
        //slkdfjhgkl
    }*/

    public ourZoom(String strTitle, java.awt.Frame parent/*, int W, int H, boolean bCreaTabella*/)
    {
        super(parent, true);
        setPreferredSize(new java.awt.Dimension(W, H));
        initComponents();
        txtRicerca.setEnabled(true);
        setTitle(strTitle);
        //this.W = 430; //W;
        //this.H = 450; //H;
        panelToolbar.setSize(W-5, 36);
        // Posiziono il dialogo al centro dello schermo
        setResizable(false);
        java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
        java.awt.Dimension screenSize = tk.getScreenSize();
        int iScrH = screenSize.height;
        int iScrW = screenSize.width;
        setBounds( (iScrW - W) / 2, (iScrH - H) / 2, W, H);
        addButtons(); // Aggiungo i pulsanti
        pnlZoom.setVisible(true);//(bCreaTabella);
        pnlZoom.setBounds(10, 110, W-27, H-200);
        tblZoom.setAutoCreateRowSorter(true);
        pnlTrova.setBounds(10, H-80, W-27, 50);
        butTrova.setBounds(pnlTrova.getWidth() - 70, butTrova.getY(), butTrova.getWidth(), butTrova.getHeight());
        txtRicerca.setBounds(txtRicerca.getX(), txtRicerca.getY(), pnlTrova.getWidth()-100, txtRicerca.getHeight());

        // Intercetto la pressione del tasto nell'header
        JTableHeader header = tblZoom.getTableHeader();
        header.addMouseListener(new ColumnHeaderListener());
                // Vincolo la slezione ad una sola riga
        tblZoom.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        // Aggiungo il keyListener per intercettare la pressione dei pulsanti
        // Cosicchè quando l'utente preme una lettera viene eseguito il filtro
        tblZoom.addKeyListener(new java.awt.event.KeyAdapter() {
            @Override
            public void keyPressed(java.awt.event.KeyEvent evt) {
                Character ch = evt.getKeyChar();
                if ( (Character.isLetter(ch)) || (Character.isSpaceChar(ch)) )
                {
                    if(Character.isSpaceChar(ch))
                    {
                        ch = '-';
                    } else {
                        ch = Character.toUpperCase(ch);
                    }

                    fetchData("" + ch, false);
                }
            }
        });
        addCustomEvents(); // Aggiungo gli eventi personalizzati
    }
    
    /**
     * Imposta la stringa-filtro di default (e che viene eseguita alla visualizzazione dello zoom)
     * @param strDefaultFilter
     */
    public void setDefaultFilter(String strDefaultFilter)
    {
        _DEFAULTFILTER = strDefaultFilter;
    }

    private boolean fetchData(String str, boolean bUsingTrovaButton)
    {
        boolean bRet = true;
        try {
            //java.sql.Connection conn = our.gui.utils.sqlMap.getCurrentConnection();
            //our.gui.utils.sqlMap.startTransaction();
            java.sql.Statement stmt = our.gui.utils.connection.createStatement();
            String strQuery = "SELECT COUNT(id) FROM " + this._DB_TABLE + " WHERE deleted=0";
            if(bUsingTrovaButton==false)
            {
                if(!str.startsWith("-"))
                {
                    strQuery += " AND " + _SORT_FIELD + " LIKE '" + str + "%'";
                }
            } else {
                strQuery += " AND " + _TROVA_FIELD + " LIKE '%" + str + "%'";
            }

            java.sql.ResultSet rs = stmt.executeQuery(strQuery);
            rs.next();
            int iTotRecs = rs.getInt(1);
            rs.close();

            if( (bUsingTrovaButton) && (iTotRecs==0) ) our.gui.utils.MessageBox("La stringa cercata è inesistente!", JOptionPane.WARNING_MESSAGE);

            Object [][] data = null;
            if (iTotRecs>0)
            {
                data = new Object[iTotRecs][_STRFIELDSONDB.length + 1];
                //strQuery = "SELECT ";
                String strFlds = "";
                for(String key : _STRFIELDSONDB) strFlds += key + ", ";
                strFlds = strFlds.substring(0, strFlds.length() - 2);
                strQuery = strQuery.replace("COUNT(id)", strFlds);
                /*strQuery = strQuery.substring(0, strQuery.length()-2);
                strQuery += " FROM " + this._DB_TABLE + " WHERE deleted=0 ";
                if(bUsingTrovaButton==false)
                {
                    if(!str.startsWith("-"))
                    {
                        strQuery += " AND " + _SORT_FIELD + " LIKE '" + str + "%'";
                    }
                } else {
                    strQuery += " AND " + _TROVA_FIELD + " LIKE '%" + str + "%'";
                }*/
                strQuery += " ORDER BY " + this._SORT_FIELD;
                setCustomCursor(Cursor.WAIT_CURSOR);
                rs = stmt.executeQuery(strQuery);
                iTotRecs = 0;
                while(rs.next())
                {
                    for(int i=0; i<_STRFIELDSONDB.length; i++) data[iTotRecs][i] = rs.getObject(_STRFIELDSONDB[i]);
                    iTotRecs++;
                }
            } else {
                if( (data==null) && (butZoom.isEnabled()) )
                {
                    our.gui.utils.MessageBox("Non ci sono campi con il parametro richiesto!", JOptionPane.WARNING_MESSAGE);
                    bRet = false;
                }
            }
            if(data!=null) populate(data);
            rs.close();
            stmt.close();
//            our.gui.utils.sqlMap.endTransaction();
        } catch (SQLException ex) {
            bRet = false;
            javax.swing.JOptionPane.showMessageDialog(this, ex, "ERRORE", javax.swing.JOptionPane.ERROR_MESSAGE);
            our.gui.utils.logger.log(Level.SEVERE, ex.toString());
        } finally {
            setCustomCursor(Cursor.DEFAULT_CURSOR);
            return bRet;
        }
    }

    /**
     * Questa funzione viene chiamata quando sono su un campo con Zoom.
     * 1) L'utente inserisce un valore;
     * 2) Preme INVIO;
     * 3) Viene invocata questa funzione e prelevato il record (i campi visibili nella griglia);
     * 4) Viene restituito all'utente null se non esiste, un array di stringhe altrimenti.
     * @param str Il prefisso da cercare
     */
    protected void findUsingKey(String str)
    {
        //_RECORDSFOUND = FILTRA(str, false);
        _RECORDSFOUND = fetchData(str, false);
        butSalvaMouseClicked(null);
    }

    /**
     * Cerca nella colonna iCol della griglia, la prima entry che una corrispondenza con la stringa str
     * @param  str La stringa da ricercare
     * @param  iCol L'indice della colonna in cui cercare
     * @return 
     */
    protected boolean searchAndMark(String str, int iCol)
    {
        if(!isVisible()) return true;
        
        if(!_ISTABLESET)
        {
            System.out.println("protected boolean searchAndMark(String str, int iCol): Non hai chiamato la funzione 'configureTableModel'");
            System.exit(1);
        }
        boolean bRet = false;
        // Se viene passato un parametro, evidenzio la prima linea che gli corrisponde
        if( (str!=null) && (!str.isEmpty()) )
        {
            int iLen = tblZoom.getModel().getRowCount();
            for(int i=0; i<iLen; i++)
            {
                if(tblZoom.getModel().getValueAt(i, iCol).toString().indexOf(str)>=0)
                {
                    Rectangle rect = tblZoom.getCellRect(i, iCol, true);
                    tblZoom.scrollRectToVisible(rect);
                    tblZoom.setRowSelectionInterval(i, i);
                    break;
                }
            }
        }
        return bRet;
    }

    /**
     * Aggiorna il contenuto della griglia in base ai dati passati nell'array
     * @param data Array contenente i dati da inserire nelle righe della griglia
     */
    protected void populate(Object[][] data)
    {
        if(!_ISTABLESET)
        {
            System.out.println("protected boolean searchAndMark(String str, int iCol): Non hai chiamato la funzione 'configureTableModel'");
            System.exit(1);
        }
        DefaultTableModel dtm = (DefaultTableModel)tblZoom.getModel();
        dtm.setDataVector(data, _STRCAPTION);
        // Se ci sono dei record nella griglia, seleziono il primo
        if(tblZoom.getRowCount()>0)
            tblZoom.setRowSelectionInterval(0, 0);
        tblZoom.requestFocus();
    }

    /**
     * Imposta i titoli delle colonne della griglia
     * @param strCaption Array contenente le intestazioni delle colonne
     * @param iDim Array contenente le dimensioni delle colonne in ordine sequenziale
     */
    protected void configureTableModel(String[] strCaption, Integer[] iDim, String[] strFieldOnDB)
    {
        _STRFIELDSONDB = strFieldOnDB;
        _STRCAPTION = strCaption;
        int iColumns = _STRFIELDSONDB.length;
        final Class[] types = new Class[iColumns];
        final boolean[] canEdit = new boolean [iColumns];
        for(int j=0; j<iColumns; j++) {
            types[j] = java.lang.String.class;
            canEdit[j] = false;
        }
        tblZoom.setModel(new javax.swing.table.DefaultTableModel(null, strCaption) {
            @Override
            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            @Override
            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        // Imposto le dimensioni delle colonne
        TableColumnModel hdr = tblZoom.getColumnModel();
        for(int i=0; i<iDim.length; i++)
            hdr.getColumn(i).setPreferredWidth(iDim[i]);

        // Disabilito l'attributo autoCreateColumnsFromModel altrimenti tutte le
        // personalizzazioni delle colonne vengono perdute in fase di ordinamento
        tblZoom.setAutoCreateColumnsFromModel(false);
        _ISTABLESET = true;
    }
    
    /**
     * public void setZoomOnZoom(boolean bEnabled)
     * @param bEnabled true per abilitare lo zoom on zoom
     *                 false altrimenti
     * Abilita/Diabilita lo zoom on zoom
     */
    public void setZoomOnZoom(boolean bEnabled)
    {
        ISZOOMONZOOMENABLED = bEnabled;
        butZoom.setEnabled(bEnabled);
    }
    
    /*public void setChild(ourZoom CHILD)
    {
        this.CHILD = CHILD;
    }*/
    
    /**
     * private void addButtons()
     * 
     * Aggiunge i pulsanti con le lettere nello zoom
     */
    private void addButtons()
    {
        // Aggiungo i pulsanti
        butLettere = new JButton[27];
        int iLinea = 50;
        int iPos = 0;
        for(int i=0; i<27; i++)
        {
            if(i==17) {
                iLinea = 75;
                iPos = 0;
            }
            butLettere[i] = new JButton();
            butLettere[i].setFont(new java.awt.Font("Tahoma", 1, 10));
            super.getContentPane().add(butLettere[i]);
            butLettere[i].setContentAreaFilled(false);
            butLettere[i].setBorder(BorderFactory.createEtchedBorder());
            butLettere[i].setFocusable(false);
            char c = (char)(i + 65);
            butLettere[i].setText("" + c);
            butLettere[i].setToolTipText("Visualizza i record che iniziano con la lettera '" + c + "'");
            butLettere[i].setActionCommand("" + c);
            butLettere[i].addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                parseDB(evt);
            }
            });
           if(i<26)               
               butLettere[i].setBounds(10+(iPos++)*25, iLinea, 23, 23);
            else
            {
               butLettere[i].setBounds(335, iLinea, 98, 23);
               butLettere[i].setText("TUTTI");
               butLettere[i].setToolTipText("Visualizza tutti i record");
               butLettere[i].setFocusable(false);
            }
        }
    }
    
    /**
     * private void addCustomEvents()
     * 
     * Aggiunge gli eventi personalizzati (F5, F9...)
     */
    private void addCustomEvents()
    {
        Action zoomOnzoom = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                butZoomMouseClicked(null);
            }
        };        
        tblZoom.getInputMap().put(KeyStroke.getKeyStroke("F2"), "F2KEY");
        tblZoom.getActionMap().put("F2KEY", zoomOnzoom);
        // Personalizzo il gestore degli eventi
        CustomEvent customEvent = new CustomEvent();
        Action f9 = new FXAction("F9", customEvent); // Salva i dati
        Action esc = new FXAction("ESC", customEvent);   // Chiudi la maschera
        Action up    = new FXAction("UP", customEvent);    // Sposta il fuoco sull'oggetto precedente
        Action down  = new FXAction("DOWN", customEvent); // Sposta il fuoco sull'oggetto successivo
        Action altT  = new FXAction("ALTT", customEvent); // Alt+T = Ricerca
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0, false), "F9");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false), "ESC");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false), "UP");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, false), "DOWN");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0, false), "DOWN");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "DOWN");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, java.awt.event.InputEvent.SHIFT_DOWN_MASK, false), "UP");
        getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_T, java.awt.event.InputEvent.ALT_DOWN_MASK, false), "ALTT");
        getRootPane().getActionMap().put("UP", up);
        getRootPane().getActionMap().put("DOWN", down);
        getRootPane().getActionMap().put("F9", f9);
        getRootPane().getActionMap().put("ESC", esc);
    }

    // Inner class
    class FXAction extends AbstractAction {
        private String key;
        private CustomEvent customEvent;
        
        public FXAction(String key, CustomEvent customEvent)
        {
            this.key = key;
            this.customEvent = customEvent;
        }

        public void actionPerformed(ActionEvent e) {
            if(customEvent!=null)
            {
                customEvent.esegui(key);
            }
        }
    }
    
    // Innser class
    class CustomEvent {
        public void esegui(String key)
        {
            if(key.equalsIgnoreCase("F9"))  butSalvaMouseClicked(null);
            if(key.equalsIgnoreCase("ESC")) butEsciMouseClicked(null);
            if(key.equalsIgnoreCase("ALTT"))
            {
                if(butTrova.isEnabled()) butTrovaActionPerformed(null);
            }
            if(key.equalsIgnoreCase("UP"))
            {
                java.awt.KeyboardFocusManager kfm = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager();
                kfm.focusPreviousComponent();
            }
            if(key.equalsIgnoreCase("DOWN"))
            {
                java.awt.KeyboardFocusManager kfm = java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager();
                kfm.focusNextComponent();
            }
        }
    }
    
    /**
     * Imposta la forma del cursore
     * @param CURSOR
     */
    public void setCustomCursor(int CURSOR)
    {
        Cursor normalCursor = new Cursor(CURSOR);
        setCursor(normalCursor);
    }
    
    private void parseDB(java.awt.event.MouseEvent evt) {
        // TODO add your handling code here:
        JButton butPressed = (JButton)evt.getSource();
        String strText = butPressed.getText();
        if(strText.equalsIgnoreCase("TUTTI")) 
            fetchData("-", false);
        else
            fetchData(strText, false);
    }
    
    /**
     * Ritorna un array di stringhe contenente tutti gli elementi selezionati
     * @return
     */
    public String[] getSelectedEntry()
    {
        if(strRet==null) return null;
        return strRet;
    }
    
    public void sortAllRowsBy(DefaultTableModel model, int colIndex, boolean ascending) {
        Vector data = model.getDataVector();
        Collections.sort(data, new our.gui.ColumnSorter(colIndex, ascending));
        model.fireTableStructureChanged();
    }
    
    class ColumnHeaderListener extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent evt) {
            JTable table = ((JTableHeader)evt.getSource()).getTable();
            TableColumnModel colModel = table.getColumnModel();
        
            // Prelevo l'indice della colonna su cui è stato effettuato il click
            int vColIndex = colModel.getColumnIndexAtX(evt.getX());
            //int mColIndex = table.convertColumnIndexToModel(vColIndex);
        
            // Ritorna se non è stato clikkato su un header
            if(vColIndex == -1)
                return;
        
            sortAllRowsBy((DefaultTableModel)tblZoom.getModel(), vColIndex, bAsc);
            bAsc = !bAsc;
        
            // Determina se il mouse è stato clikkato tra gli header delle colonne
            Rectangle headerRect = table.getTableHeader().getHeaderRect(vColIndex);
            if(vColIndex == 0) {
                headerRect.width -= 3;
            } else {
                headerRect.grow(-3, 0);
            }
            if(!headerRect.contains(evt.getX(), evt.getY())) {
                // Il Mouse è stato clickkato tra gli header
                // vColIndex è l'header più della colonna più vicina
                // vLeftColIndex è l'header della colonna alla sinistra del click
                int vLeftColIndex = vColIndex;
                if(evt.getX() < headerRect.x) {
                    vLeftColIndex--;
                }
            }
        }    
    }    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        panelToolbar = new javax.swing.JPanel();
        butSalva = new javax.swing.JButton();
        butEsci = new javax.swing.JButton();
        butPrnscr = new javax.swing.JButton();
        butInfo = new javax.swing.JButton();
        butZoom = new javax.swing.JButton();
        pnlZoom = new javax.swing.JScrollPane();
        tblZoom = new javax.swing.JTable();
        pnlTrova = new javax.swing.JPanel();
        butTrova = new our.gui.ourButton();
        txtRicerca = new our.gui.ourTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowOpened(java.awt.event.WindowEvent evt) {
                formWindowOpened(evt);
            }
        });
        getContentPane().setLayout(null);

        panelToolbar.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        panelToolbar.setLayout(null);

        butSalva.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar1.gif"))); // NOI18N
        butSalva.setToolTipText("Conferma");
        butSalva.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butSalva.setFocusable(false);
        butSalva.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butSalvaMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butSalvaMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butSalvaMouseExited(evt);
            }
        });
        panelToolbar.add(butSalva);
        butSalva.setBounds(10, 5, 26, 26);

        butEsci.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar2.gif"))); // NOI18N
        butEsci.setToolTipText("Esci");
        butEsci.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butEsci.setFocusable(false);
        butEsci.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butEsciMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butEsciMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butEsciMouseExited(evt);
            }
        });
        panelToolbar.add(butEsci);
        butEsci.setBounds(38, 5, 26, 26);

        butPrnscr.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar14.gif"))); // NOI18N
        butPrnscr.setToolTipText("Print Screen");
        butPrnscr.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butPrnscr.setFocusable(false);
        butPrnscr.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butPrnscrMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butPrnscrMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butPrnscrMouseExited(evt);
            }
        });
        panelToolbar.add(butPrnscr);
        butPrnscr.setBounds(380, 5, 26, 26);

        butInfo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar15.gif"))); // NOI18N
        butInfo.setToolTipText("Help");
        butInfo.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butInfo.setEnabled(false);
        butInfo.setFocusable(false);
        butInfo.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butInfoMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butInfoMouseExited(evt);
            }
        });
        panelToolbar.add(butInfo);
        butInfo.setBounds(408, 5, 26, 26);

        butZoom.setIcon(new javax.swing.ImageIcon(getClass().getResource("/our/gui/img/toolbar7.gif"))); // NOI18N
        butZoom.setToolTipText("Zoom");
        butZoom.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        butZoom.setEnabled(false);
        butZoom.setFocusable(false);
        butZoom.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                butZoomMouseClicked(evt);
            }
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                butZoomMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                butZoomMouseExited(evt);
            }
        });
        panelToolbar.add(butZoom);
        butZoom.setBounds(258, 5, 26, 26);

        getContentPane().add(panelToolbar);
        panelToolbar.setBounds(0, 0, 450, 36);

        tblZoom.setFont(new java.awt.Font("Dialog", 0, 10));
        tblZoom.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        tblZoom.setNextFocusableComponent(txtRicerca);
        tblZoom.getTableHeader().setReorderingAllowed(false);
        tblZoom.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tblZoomMouseClicked(evt);
            }
        });
        tblZoom.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                tblZoomKeyPressed(evt);
            }
        });
        pnlZoom.setViewportView(tblZoom);

        getContentPane().add(pnlZoom);
        pnlZoom.setBounds(20, 70, 400, 160);

        pnlTrova.setBorder(javax.swing.BorderFactory.createTitledBorder(javax.swing.BorderFactory.createEtchedBorder(), "Ricerca nella descrizione", javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("DejaVu Sans", 0, 13), new java.awt.Color(0, 102, 255))); // NOI18N
        pnlTrova.setLayout(null);

        butTrova.setText("Trova");
        butTrova.setNextFocusableComponent(tblZoom);
        butTrova.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                butTrovaActionPerformed(evt);
            }
        });
        pnlTrova.add(butTrova);
        butTrova.setBounds(330, 20, 60, 20);

        txtRicerca.setCharsInputAllowed(2);
        txtRicerca.setEnabled(true);
        txtRicerca.setHelpMsg("Inserisci qui il termine da cercare");
        txtRicerca.setMaxTextLength(40);
        txtRicerca.setNextFocusableComponent(butTrova);
        txtRicerca.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                txtRicercaKeyTyped(evt);
            }
        });
        pnlTrova.add(txtRicerca);
        txtRicerca.setBounds(10, 20, 310, 20);

        getContentPane().add(pnlTrova);
        pnlTrova.setBounds(10, 350, 410, 50);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void butPrnscrMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseEntered
        // TODO add your handling code here:
        butPrnscr.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butPrnscrMouseEntered

    private void butPrnscrMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseExited
        // TODO add your handling code here:
        butPrnscr.setBorder(our.gui.ourForm.BUT_BORDER_EXITING);
    }//GEN-LAST:event_butPrnscrMouseExited

    private void butInfoMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butInfoMouseEntered
        // TODO add your handling code here:
        butInfo.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butInfoMouseEntered

    private void butInfoMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butInfoMouseExited
        // TODO add your handling code here:
        butInfo.setBorder(our.gui.ourForm.BUT_BORDER_EXITING);
    }//GEN-LAST:event_butInfoMouseExited

    private void tblZoomMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tblZoomMouseClicked
        // TODO add your handling code here:
        if(evt.getClickCount() == 2)
        {
            evt.consume();
            butSalvaMouseClicked(null);
        }
}//GEN-LAST:event_tblZoomMouseClicked

    private void tblZoomKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tblZoomKeyPressed
        // TODO add your handling code here:
        if(evt.getKeyCode() == KeyEvent.VK_ENTER)
            butSalvaMouseClicked(null);
        // L'utente preme SHIFT+TAB
        if( (evt.getKeyCode() == java.awt.event.KeyEvent.VK_TAB ) &&
            (evt.isShiftDown()) )
        {
            evt.consume();
            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
            kfm.focusPreviousComponent();
        }
        // L'utente preme TAB
        if( (evt.getKeyCode() == java.awt.event.KeyEvent.VK_TAB) &&
            (!evt.isShiftDown()) )
        {
            evt.consume();
            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
            kfm.focusNextComponent();
        }

        // L'utente preme il pulsante 'Sù'
        if ( (evt.getKeyCode() == java.awt.event.KeyEvent.VK_UP) &&
            (evt.isActionKey()) && (tblZoom.getSelectedRow() == 0) )
        {
            // Sposto il fuoco all'elemento precedente alla griglia
            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
            kfm.focusPreviousComponent();
        }

        // L'utente preme il pulsante 'Giù'
        if( (evt.getKeyCode() == java.awt.event.KeyEvent.VK_DOWN) &&
            (evt.isActionKey()) &&
            (tblZoom.getSelectedRow() == (tblZoom.getRowCount() - 1)) )
        {
            // Il l'elemento della griglia selezionato è l'utlimo e
            // l'utente preme il tasto 'giù', passo il fuoco all'elemento successivo
            KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
            kfm.focusNextComponent();
        }
    }//GEN-LAST:event_tblZoomKeyPressed

    private void butZoomMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseClicked
        // TODO add your handling code here:
        String strRetTmp[] = null;

        if(butZoom.isEnabled())
        {
            int iSel = tblZoom.getSelectedRow();
            if(iSel>=0)
            {
                strRetTmp = new String[1];
                strRetTmp[0] = tblZoom.getModel().getValueAt(iSel, 0).toString();
                strRetTmp[0] = tblZoom.getModel().getValueAt(iSel, 1).toString();
            }
            //java.util.HashMap<String, String> hm = new java.util.HashMap<String, String>();
            //hm.put(_STRFIELDSONDB[0], strRetTmp[0]);
            Object[] objTmp = CallZoom(strRetTmp);
            //Object[] objTmp = CALLZOOM(strRetTmp);
            //Object[] objTmp = CALLZOOM(hm);
            if(objTmp[0].toString().length()!=0)
            {
                // Nascondo la finestra
                setVisible(false);
                // L'utente ha premuto F9 quindi devo portarmi dietro i valori salvati
                fetchData(objTmp[0].toString(), false);
                butSalvaMouseClicked(null);
            }
        }
    }//GEN-LAST:event_butZoomMouseClicked

    private void butZoomMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseEntered
        // TODO add your handling code here:
        butZoom.setBorder(BorderFactory.createEtchedBorder());
    }//GEN-LAST:event_butZoomMouseEntered

    private void butZoomMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butZoomMouseExited
        // TODO add your handling code here:
        butZoom.setBorder(our.gui.ourForm.BUT_BORDER_EXITING);
    }//GEN-LAST:event_butZoomMouseExited

    private void butTrovaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_butTrovaActionPerformed
        // TODO add your handling code here:
        fetchData(txtRicerca.getText(), true);
        txtRicerca.requestFocus();
    }//GEN-LAST:event_butTrovaActionPerformed

    private void butEsciMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseExited
        // TODO add your handling code here:
        butEsci.setBorder(our.gui.ourForm.BUT_BORDER_EXITING);
}//GEN-LAST:event_butEsciMouseExited

    private void butEsciMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseEntered
        // TODO add your handling code here:
        butEsci.setBorder(BorderFactory.createEtchedBorder());
}//GEN-LAST:event_butEsciMouseEntered

    private void butEsciMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butEsciMouseClicked
        // TODO add your handling code here:
        // Il controllo della visibilità serve quando lo zoom è visibile e non è stato chiamato
        // per verificare l'esistenza di un campo: ad es un utente inserisci un codice e preme INVIO

        if(isVisible()) //setVisible(false);
            dispose();
}//GEN-LAST:event_butEsciMouseClicked

    private void butSalvaMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseExited
        // TODO add your handling code here:
        butSalva.setBorder(our.gui.ourForm.BUT_BORDER_EXITING);
}//GEN-LAST:event_butSalvaMouseExited

    private void butSalvaMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseEntered
        // TODO add your handling code here:
        butSalva.setBorder(BorderFactory.createEtchedBorder());
}//GEN-LAST:event_butSalvaMouseEntered

    private void butSalvaMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butSalvaMouseClicked
        // TODO add your handling code here:
        if(_RECORDSFOUND)
        {
            int iSel = tblZoom.getSelectedRow();
            if(iSel>=0) {
                strRet = new String[_STRCAPTION.length];
                for(int i=0; i<_STRCAPTION.length; i++)
                {
                    if(tblZoom.getModel().getValueAt(iSel, i)==null)
                        strRet[i] = "";
                    else
                        strRet[i] = tblZoom.getModel().getValueAt(iSel, i).toString();
                }
            } else {
                _RECORDSFOUND = false;
            }
        }
        butEsciMouseClicked(null);
}//GEN-LAST:event_butSalvaMouseClicked

private void formWindowOpened(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowOpened
    // Posiziono il dialogo al centro dello schermo
    /*setResizable(false);
    java.awt.Toolkit tk = java.awt.Toolkit.getDefaultToolkit();
    java.awt.Dimension screenSize = tk.getScreenSize();
    int iScrH = screenSize.height;
    int iScrW = screenSize.width;
    setBounds( (iScrW - W) / 2, (iScrH - H) / 2, W, H);*/
    fetchData(_DEFAULTFILTER, false);
}//GEN-LAST:event_formWindowOpened

private void butPrnscrMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_butPrnscrMouseClicked
    // TODO add your handling code here:
    try {
            String fileName = javax.swing.JOptionPane.showInputDialog(null, "Nome del file : ", "Screen Capture", 1);
            if(fileName==null || fileName.length()==0) throw new Exception("User abort!");
            fileName = System.getProperty("user.home") + System.getProperty("file.separator") + fileName + ".gif";
            java.awt.Robot robot = new java.awt.Robot();
            java.awt.image.BufferedImage image = robot.createScreenCapture(new java.awt.Rectangle(
            java.awt.Toolkit.getDefaultToolkit().getScreenSize()));
            javax.imageio.ImageIO.write(image, "gif", new java.io.File(fileName));
            javax.swing.JOptionPane.showMessageDialog(null, "Cattura dello schermo completata in \n" + fileName,
                "Screen Capture", 1);
    } catch(Exception e) {} finally { }
}//GEN-LAST:event_butPrnscrMouseClicked

private void txtRicercaKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtRicercaKeyTyped
    // TODO add your handling code here:
    if(evt.getKeyChar()==(char)java.awt.event.KeyEvent.VK_ENTER) butTrovaActionPerformed(null);
}//GEN-LAST:event_txtRicercaKeyTyped
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton butEsci;
    private javax.swing.JButton butInfo;
    private javax.swing.JButton butPrnscr;
    private javax.swing.JButton butSalva;
    private our.gui.ourButton butTrova;
    protected javax.swing.JButton butZoom;
    private javax.swing.JPanel panelToolbar;
    protected javax.swing.JPanel pnlTrova;
    protected javax.swing.JScrollPane pnlZoom;
    protected javax.swing.JTable tblZoom;
    private our.gui.ourTextField txtRicerca;
    // End of variables declaration//GEN-END:variables
  
}
